/*
-------------------------------------------------

	Windows.cpp

	Dmitriy Kuzmenko (Dgut)

-------------------------------------------------
*/

#include "Autumn.h"
#include "Common.h"
#include "Input.h"
#include <windows.h>

#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif	// !!! _DEBUG !!!

HWND g_hWnd = 0;
HDC g_hDC = 0;
HGLRC g_hRC = 0;
int g_width = 0;
int g_height = 0;

bool g_active = false;

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg )
	{
	case WM_CLOSE:
		PostQuitMessage( 0 );
		break;

	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
		Autumn::gInput.Key( ( lParam >> 16 ) & 0xFF, true );
		break;

	case WM_SYSKEYUP:
	case WM_KEYUP:
		Autumn::gInput.Key( ( lParam >> 16 ) & 0xFF, false );
		break;

	case WM_SIZE:
		g_width = LOWORD( lParam );
		g_height = HIWORD( lParam );
		if( !g_width )
			g_width = 1;
		if( !g_height )
			g_height = 1;
		Autumn::gCommon.Resize( g_width, g_height );
		break;

	case WM_LBUTTONDOWN:
	case WM_MOUSEMOVE:
		if( wParam == MK_LBUTTON )
		{
			float points[ 2 ] = { LOWORD( lParam ), g_height - HIWORD( lParam ) };
			Autumn::gInput.Touch( points, 1 );
		}
		break;

	case WM_LBUTTONUP:
		Autumn::gInput.Touch( 0, 0 );
		break;

	case WM_ACTIVATE:
		g_active = LOWORD( wParam ) != WA_INACTIVE;
		break;
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{
#ifdef _DEBUG
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ | _CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif	// !!! _DEBUG !!!

 	{
		WNDCLASS wc;

		wc.cbClsExtra		= 0;
		wc.cbWndExtra		= 0;
		wc.hbrBackground	= ( HBRUSH )COLOR_GRAYTEXT;
		wc.hCursor			= LoadCursor( 0, IDC_ARROW );
		wc.hIcon			= 0;
		wc.hInstance		= hInstance;
		wc.lpfnWndProc		= WndProc;
		wc.lpszClassName	= Autumn::WNDCLASS_NAME;
		wc.lpszMenuName		= 0;
		wc.style			= CS_HREDRAW | CS_VREDRAW;

		if( !RegisterClass( &wc ) )
			return 0;

		RECT rect;

		rect.left = 0;
		rect.top = 0;
		rect.right = Autumn::WND_WIDTH;
		rect.bottom = Autumn::WND_HEIGHT;

		AdjustWindowRect( &rect, Autumn::WND_STYLE, false );

		g_hWnd = CreateWindowEx(
			0,
			Autumn::WNDCLASS_NAME,
			Autumn::WNDCLASS_NAME,
			Autumn::WND_STYLE,
			CW_USEDEFAULT, CW_USEDEFAULT,
			rect.right	- rect.left,
			rect.bottom	- rect.top,
			0,
			0,
			hInstance,
			0 );

		if( !g_hWnd )
		{
			UnregisterClass( Autumn::WNDCLASS_NAME, hInstance );
			return 0;
		}

		ShowWindow( g_hWnd, SW_SHOW );
		UpdateWindow( g_hWnd );
		
		if( !( g_hDC = GetDC( g_hWnd ) ) )
			return 0;
	
		PIXELFORMATDESCRIPTOR pfd =
		{
			sizeof( PIXELFORMATDESCRIPTOR ),
			1,
			PFD_DRAW_TO_WINDOW |
			PFD_SUPPORT_OPENGL |
			PFD_DOUBLEBUFFER,
			PFD_TYPE_RGBA,
			32,
			0, 0, 0, 0, 0, 0,
			0,
			0,
			0,
			0, 0, 0, 0,
			16,
			0,
			0,
			PFD_MAIN_PLANE,
			0,
			0, 0, 0
		};
	
		int iPixelFormat;
		if( !( iPixelFormat = ChoosePixelFormat( g_hDC, &pfd ) ) )
			return 0;
		if( !( SetPixelFormat( g_hDC, iPixelFormat, &pfd ) ) )
			return 0;
		if( !( g_hRC = wglCreateContext( g_hDC ) ) )
			return 0;
		if( !wglMakeCurrent( g_hDC, g_hRC ) )
			return 0;
	}
	
	if( !Autumn::gCommon.Init() )
	{
		Autumn::gCommon.Shutdown();
		return 0;
	}
	
	MSG msg;

	for( ; ; )
	{
		while( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) )
		{
			if( !GetMessage( &msg, 0, 0, 0 ) )
			{
				Autumn::gCommon.Shutdown();
				return 0;
			}

			TranslateMessage( &msg );
   			DispatchMessage( &msg );
		}

		Autumn::gCommon.Frame();
		
		SwapBuffers( g_hDC );
	}
 	
 	return 0;
}